﻿using MediaInfoDotNet;
using SimpleConnection_UDP_WIN.utils;
using System;
using System.Collections;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Reflection;
using System.Threading.Tasks;
using System.Windows.Forms;
using VideoMergeSplitApp.data;
using VideoMergeSplitApp.ui;
using VideoMergeSplitApp.ui.dialog;
using VideoMergeSplitApp.utils;
using WindowsImageCompressionApp.utils;

namespace VideoMergeSplitApp
{
    public partial class Form1 : Form
    {

        ArrayList videoList = new ArrayList();

        public Form1()
        {
            InitializeComponent();
        }

        private void listView1_DragEnter(object sender, DragEventArgs e)
        {
            if (e.Data.GetDataPresent(DataFormats.FileDrop))
                e.Effect = DragDropEffects.Copy;
            else
                e.Effect = DragDropEffects.None;
        }

        private void listView1_DragDrop(object sender, DragEventArgs e)
        {
            string[] files = (string[])e.Data.GetData(DataFormats.FileDrop);
            foreach (string filePath in files)
            {
                addList(filePath);
            }
        }


        long timeTotal;
        //添加数据到 list和 列表
        public void addList(string filePath)
        {

            FileInfo fileInfo = new FileInfo(filePath);

            if (!fileInfo.IsReadOnly)
            {
                //添加 list 数据
                videoList.Add(filePath);

                MediaFile mediaFile = new MediaFile(filePath);
                string resolution = mediaFile.Video[0].Width + "x" + mediaFile.Video[0].Height;

                // 添加列表项
                ListViewItem item1 = new ListViewItem(fileInfo.Name); // 第一列的值
                item1.SubItems.Add(fileInfo.Extension); // 添加其他列的值
                item1.SubItems.Add(resolution); // 添加其他列的值
                timeTotal += mediaFile.Video[0].duration;
                TimeSpan duration = TimeSpan.FromMilliseconds(mediaFile.Video[0].duration); // 将毫秒转换为TimeSpan对象

                item1.SubItems.Add($"{duration.Hours}:{duration.Minutes}:{duration.Seconds}"); // 添加其他列的值
                item1.SubItems.Add(DBUtil.FormatFileSize(fileInfo.Length)); // 添加其他列的值

                listView1.Items.Add(item1);
            }


        }
        //删除数据到 list和 列表
        private void delList(int count)
        {

            videoList.RemoveAt(count);
            listView1.Items.RemoveAt(count);
        }


        private void button6_Click(object sender, EventArgs e)
        {
            videoList.Clear();
            listView1.Items.Clear();
        }



        private void button5_Click(object sender, EventArgs e)
        {
            OpenFileDialog openFileDialog = new OpenFileDialog
            {
                Filter = "视频文件|*.mp4;", // 过滤视频文件的扩展名
                Title = "选择视频文件", // 弹窗标题
                Multiselect = true, // 设置为可以多选文件
                RestoreDirectory = true
            };

            if (openFileDialog.ShowDialog() == DialogResult.OK)
            {
                string[] selectedFiles = openFileDialog.FileNames;
                // 处理选中的文件
                foreach (string file in selectedFiles)
                {
                    // 处理文件逻辑，例如将文件路径添加到列表中
                    addList(file);
                }
            }
        }


        int operationDuration = 0;

        private void button1_Click(object sender, EventArgs e)
        {

            if (videoList.Count <= 1)
            {
                MessageBox.Show("请先添加两个以上视频文件", "提示");
                return;
            }

            SaveFileDialog saveFileDialog = new SaveFileDialog
            {
                Filter = "视频文件|*.mp4", // 设置保存文件的类型，这里以.mp4为例
                Title = "保存视频文件", // 设置保存文件对话框的标题
                RestoreDirectory = true
            };


            if (saveFileDialog.ShowDialog() == DialogResult.OK)
            {
                string outPath = saveFileDialog.FileName;

                string filePath = "src/filelist.txt";
                FileInfo fileinfo = new FileInfo(filePath);

                using (StreamWriter writer = new StreamWriter(filePath))
                {
                    //检查文件是否存在
                    foreach (string item in videoList)
                    {
                        if (!File.Exists(item))
                        {
                            toolStripStatusLabel1.Text = "当前合成列表中有文件丢失";
                            return;
                        }
                        writer.WriteLine($@"file '{item}'");
                    }

                }

                toolStripStatusLabel1.Text = "开始合成...";
                operationDuration = 0;
                timer1.Start();
                button1.Enabled = false;


                _ = Task.Run(() =>
                {

                    string output = CmdUtil.RunFFCmd($" -f concat -safe 0 -i \"{fileinfo}\" -c copy \"{outPath}\"");
                    // await Console.Out.WriteLineAsync(output);

                    // 更新UI的代码
                    this.Invoke(new Action(() =>
                    {
                        button1.Enabled = true;

                        timer1.Stop();

                        if (!File.Exists(outPath))
                        {
                            toolStripStatusLabel1.Text = "合并失败";
                            return;
                        }
                        toolStripStatusLabel1.Text = "合并完成";

                        TimeSpan duration = TimeSpan.FromMilliseconds(timeTotal); // 将毫秒转换为TimeSpan对象

                        if (menuItem8.Checked)
                            SoundUtil.playReminderTone();

                        // 在这里更新UI控件的内容
                        MessageBox.Show($"操作完成，请自行查看文件完整性，新视频文件的理论时长为 {duration.Hours}小时{duration.Minutes}分{duration.Seconds}秒\n{output}", "提示");

                        if (menuItem2.Checked)
                            DBUtil.openExplorerDir(new FileInfo(outPath).DirectoryName);



                    }));
                });




            }


        }

        private void Form1_Load(object sender, EventArgs e)
        {

            // 检查文件是否存在
            if (!File.Exists(Constant.FFMPEG_PATH))
            {
                MessageBox.Show("ffmpeg文件不存在");
            }

        }


        private void linkLabel1_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            DBUtil.openLink(@"https://t1.daumcdn.net/potplayer/PotPlayer/Version/Latest/PotPlayerSetup64.exe");
        }

        private void button2_Click(object sender, EventArgs e)
        {
            OpenFileDialog openFileDialog = new OpenFileDialog();
            openFileDialog.Filter = "视频文件|*.mp4;"; // 过滤视频文件的扩展名
            openFileDialog.Title = "选择视频文件"; // 弹窗标题

            if (openFileDialog.ShowDialog() == DialogResult.OK)
            {
                string selectedFile = openFileDialog.FileName;

                initChai(selectedFile);

            }
        }


        private string chaiVideoPath = "";
        private int chaiCount = 1;

        private void initChai(string videoPath)
        {
            chaiVideoPath = videoPath;
            //计数器归1
            chaiCount = 1;

            textBox1.Text = videoPath;
            // 处理选中的文件
            // 加载视频第一帧并显示在PictureBox控件上
            pictureBox1.Image = GetFirstFrame(videoPath);

            MediaFile mediaFile = new MediaFile(videoPath);
            TimeSpan duration = TimeSpan.FromMilliseconds(mediaFile.Video[0].duration); // 将毫秒转换为TimeSpan对象
            label2.Text = $"视频时长:{duration.Hours}:{duration.Minutes}:{duration.Seconds}";
        }



        // 获取视频的第一帧图像
        public Image GetFirstFrame(string videoPath)
        {
            //清理缓存
            if (File.Exists("tmp.jpg"))
            File.Delete("tmp.jpg");

            Image im = null;

            Task.Run(() =>
            {
                CmdUtil.RunFFCmd($" -i \"{videoPath}\" -ss 1 -f image2 tmp.jpg");
                string imgPath = Path.Combine(Environment.CurrentDirectory, "tmp.jpg");
                Console.WriteLine("图片 " + imgPath);

                // 更新UI的代码
                this.Invoke(new Action(() =>
                {
                    if (File.Exists(imgPath))
                        using (FileStream fs = new FileStream(imgPath, FileMode.Open))
                        {
                            pictureBox1.Image = Image.FromStream(fs);
                        }
                }));
            });

            return im;
        }

        private void tabPage2_DragDrop(object sender, DragEventArgs e)
        {
            string filePath = ((string[])e.Data.GetData(DataFormats.FileDrop))[0];
            initChai(filePath);
        }

        private void tabPage2_DragEnter(object sender, DragEventArgs e)
        {
            if (e.Data.GetDataPresent(DataFormats.FileDrop))
                e.Effect = DragDropEffects.Copy;
            else
                e.Effect = DragDropEffects.None;
        }

        private void button3_Click(object sender, EventArgs e)
        {
            if (string.IsNullOrEmpty(chaiVideoPath))
            {
                MessageBox.Show("请先选择视频文件", "提示");
                return;
            }

            InputDialogBox2 inputDialogBox2 = new InputDialogBox2();
            inputDialogBox2.ShowDialog();

            if (!string.IsNullOrEmpty(inputDialogBox2.res))
            {

                //判断 
                MediaFile mediaFile = new MediaFile(chaiVideoPath);
                int chaiDuration = mediaFile.Video[0].duration;

                double inputDuration = TimeSpan.Parse(inputDialogBox2.res).TotalMilliseconds;

                if (inputDuration > chaiDuration || inputDuration < 1)
                {
                    MessageBox.Show("输入的时长不能小于1秒或大于视频总时长", "提示");
                    return;
                }


                chaiFun(inputDialogBox2.res);

            }
        }

        /// <summary>
        /// 拆分函数  传入输出路径和每段时长
        /// </summary>
        /// <param name="timeStr"></param>
        private void chaiFun(string timeStr)
        {

            SaveFileDialog saveFileDialog = new SaveFileDialog
            {
                Filter = "视频文件|*.mp4", // 设置保存文件的类型，这里以.mp4为例
                Title = "保存视频文件" // 设置保存文件对话框的标题
            };

            if (saveFileDialog.ShowDialog() == DialogResult.OK)
            {
                toolStripStatusLabel1.Text = "开始拆分...";
                operationDuration = 0;
                timer1.Start();

                _ = Task.Run(() =>
                {

                    FileInfo fi = new FileInfo(saveFileDialog.FileName);
                    string outFileName = fi.Directory.FullName + @"\" + fi.Name.Replace(fi.Extension, "") + "_%d" + fi.Extension;

                    string cmd = $" -i \"{chaiVideoPath}\" -c copy -map 0 -segment_time \"{timeStr}\" -f segment \"{outFileName}\"";
                    string output = CmdUtil.RunFFCmd(cmd);

                    // 更新UI的代码
                    this.Invoke(new Action(() =>
                    {
                        toolStripStatusLabel1.Text = "拆分完成";
                        timer1.Stop();

                        if (menuItem8.Checked)
                            SoundUtil.playReminderTone();

                        // 在这里更新UI控件的内容
                        MessageBox.Show($"操作完成，请自行查看文件完整性，当前拆分情况下每段视频理论时长为{timeStr}\n{output}", "提示");

                        if (menuItem2.Checked)
                            DBUtil.openExplorerDir(fi.DirectoryName);

                    }));
                });
            }


        }




        private void button4_Click(object sender, EventArgs e)
        {
            if (string.IsNullOrEmpty(chaiVideoPath))
            {
                MessageBox.Show("请先选择视频文件", "提示");
                return;
            }

            InputDialogBox1 inputDialogBox1 = new InputDialogBox1();
            inputDialogBox1.ShowDialog();

            if (inputDialogBox1.res != 0)
            {

                MediaFile mediaFile = new MediaFile(chaiVideoPath);
                int chaiDuration = mediaFile.Video[0].duration;

                int danDuration = (chaiDuration / inputDialogBox1.res);

                TimeSpan timespan = TimeSpan.FromMilliseconds(danDuration); // 将毫秒转换为TimeSpan对象

                chaiFun($"{timespan.Hours}:{timespan.Minutes}:{timespan.Seconds}");

            }
        }

        private void button7_Click(object sender, EventArgs e)
        {
            if (string.IsNullOrEmpty(chaiVideoPath))
            {
                MessageBox.Show("请先选择视频文件", "提示");
                return;
            }
            BatchSplittingForm batchSplittingForm = new BatchSplittingForm(chaiVideoPath);
            batchSplittingForm.Show();

        }

        private void menuItem2_Click(object sender, EventArgs e)
        {
            menuItem2.Checked = !menuItem2.Checked;
        }


        private void menuItem5_Click(object sender, EventArgs e)
        {
            MessageBox.Show(File.ReadAllText(Constant.HELP_PATH), "帮助文档");
        }

        private void menuItem7_Click(object sender, EventArgs e)
        {
            MessageBox.Show("本软件基于ffmpeg进行实际视频处理操作\n开发者：明灯花月夜");
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            operationDuration++;
            toolStripStatusLabel2.Text = $"操作时长：{DBUtil.FormatSeconds(operationDuration)}";
        }

        private void menuItem6_Click(object sender, EventArgs e)
        {
            BatchCompressionOfVideos batchCompressionOfVideos = new BatchCompressionOfVideos(); 
            batchCompressionOfVideos.Show();
        }

        private void listView1_KeyDown(object sender, KeyEventArgs e)
        {
            //使用Delete删除表项和对象
            if (Keys.Delete == e.KeyCode)
            {
                foreach (ListViewItem listViewItem in ((ListView)sender).SelectedItems)
                {
                    //首先获取索引 并删除对象，其次删除表项
                    videoList.RemoveAt(listViewItem.Index);
                    listViewItem.Remove();
                }
            }

        }
    }
}
